/**
 * 根据指定的卡片模型删除数据
 *
 * 输入参数:
 *   Card:       必需,     文本,            卡片名称
 *   Record:     可选,     对象,            要删除的记录对象, 至少要包含ID字段, 引用对象支持级联删除
 *   Records:    可选,     对象数组,        要批量删除的记录数组
 *   ID:         可选,     文本,            要删除的记录ID
 *   Children:   可选,     键值对象,        指定要同步删除的子表. 格式为: {卡片名称:引用名称}
 *   Safe:       可选,     布尔,            是否安全删除. 如果存在删除标记会假删, 不存在会检测所有引用, 避免误删正在被引用的数据
 *
 * 输出参数:
 *   true表示删除成功. 任意记录删除失败都会抛出异常, 但不保证原子性
 *   使用删除标记进行安全删除时, 如果一次删除的记录数量超过1000条, 删除标记的值会重复, 可能会违反包含删除标记的组合唯一索引
 *
 *   Created by wbx on 2022/5/1
 */
(function () {
  function CardD({ UID, Card, Record, Records, ID, Children, Safe = false }) {
    // 验证用户
    if (!UID) throw Error("未授权的访问");

    const card = A.card[Card];

    // 参数处理
    let ids = [];
    if (Record) {
      ids.push(Record.ID);
    }
    if (Records) {
      ids.push(...Records.map(r => r.ID));
    }
    if (ID) {
      ids.push(ID);
    }

    // 处理子表的删除策略
    const children_del = [];
    const children_referids = [];
    if (Children) {
      Object.keys(Children).forEach(kpmc => {
        let c = A.card[kpmc];
        let field = c.引用[Children[kpmc]].标识符;
        children_referids.push(c.引用[Children[kpmc]].ID);
        children_del.push(id => {
          if (Safe) {
            const { rows } = A.db.execute(c.连接名称, `SELECT ID FROM ${c.标识符} WHERE ${field}=?`, [id]);
            A.job.CardD({ UID, Card: kpmc, Records: rows, Safe });
          } else {
            A.db.execute(c.连接名称, `DELETE FROM ${c.标识符} WHERE ${field}=?`, [id]);
          }
        });
      });
    }

    // 安全删除的检查
    if (Safe && !card.数据.删除标记) {
      // 查询所有引用方
      let { rows } = A.db.execute('KERNEL', "SELECT A.LJMC, A.MC KPMC, A.BSF KPBSF, B.ID YYID, B.BSF YYBSF FROM KP A, KPYY B WHERE A.ID=B.KP_ID AND B.MB_ID=?", [card.ID]);
      rows.forEach(row => {
        // 排除子表
        if (children_referids.includes(row.YYID)) return;
        ids.forEach(id => {
          let result;
          try {
            let { rows: [res] } = A.db.execute(row.LJMC, `SELECT COUNT(*) N FROM ${row.KPBSF} WHERE ${row.YYBSF}=?`, [id]);
            result = res;
          }
          // 忽略不能连接的
          catch (e) { }
          if (result && result.N > 0) throw Error(`要删除的记录正在被[${row.KPMC}]使用`);
        });
      });
    }

    // 执行删除 (每批次1000条)
    do {
      const base_ticks = Date.now() * 1000;
      ids.splice(0, 1000).forEach((id, index) => {
        children_del.forEach(del => del(id));
        if (Safe && card.数据.删除标记) {
          card.save({ ID: id, 删除标记: base_ticks + index }, UID);
        } else {
          card.delete(id);
        }
      });
    } while (ids.length > 0)

    return true;
  }

  return (arg1, arg2, arg3) => {
    if (typeof arg1 === 'string' && typeof arg2 === 'string') {
      let other = {};
      if (typeof arg3 === 'string') {
        other.ID = arg3;
      } else if (Array.isArray(arg3)) {
        other.Records = arg3;
      } else {
        other.Record = arg3;
      }
      return CardD({
        UID: arg1,
        Card: arg2,
        ...other
      });
    } else {
      // 检查卡片访问控制表
      if (arg2 && A.setting('EnableCardACL')) {
        const acl = A.cache.get(`CardACL.${arg1.Card}`, () => {
          return A.db.execute('KERNEL', "SELECT * FROM KPFWKZ WHERE KPMC=?", [arg1.Card]).rows;
        }, 60); // 缓存60秒
        if (!acl.some(item => !!item.KFKS) && !A.job.JobEvent({
          Event: 'OnCheckPageACL',
          UID: arg1.UID,
          PageIds: acl.filter(item => item.GLYM_ID).map(item => item.GLYM_ID),
        }, arg2)) {
          throw Error("You are not authorized to access this card");
        }
      }
      return CardD(arg1);
    }
  };
})()